package com.yfbao.horizon.schedule.tk.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.LinkedHashMap;

/**
 * json序列化,序列化时保存对象类型到json字符串中
 */
@Slf4j
public class JacksonSerializer {
    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
//        objectMapper.disable(MapperFeature.USE_ANNOTATIONS);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        SimpleModule simpleModule = new SimpleModule();
        objectMapper.registerModule(simpleModule);
//        DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig();
//        objectMapper.setConfig(deserializationConfig);
        //设置序列化时放入对象类型到json str
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, DefaultTyping.EVERYTHING);
    }

    public static <T> T deserialize(byte[] data) {
        return (T) deserialize(data, Object.class);
    }

    public static <T> T deserialize(byte[] data, Class<T> tClass) {
        ClassLoader originClassloader = Thread.currentThread().getContextClassLoader();
        try {
            if (data != null) {
                //性能日志埋伏
                if (tClass.getClassLoader() != null) {
                    Thread.currentThread().setContextClassLoader(tClass.getClassLoader());
                }
                return objectMapper.readValue(data, tClass);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            Thread.currentThread().setContextClassLoader(originClassloader);
        }
        return null;
    }

    public static byte[] serialize(Object obj) {
        try {
            byte[] data = objectMapper.writeValueAsBytes(obj);
            return data;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

}
